import { Layer } from './Layer';
import type { GameObject } from './GameObject';

export class Engine {
  private readonly ctx: CanvasRenderingContext2D;
  private layers: Layer[] = [];
  private lastFrameTime = 0;
  private isRunning = false;

  constructor(ctx: CanvasRenderingContext2D) {
    this.ctx = ctx;
  }

  addLayer(layer: Layer): void {
    layer.engine = this;
    this.layers.push(layer);
  }

  async start(): Promise<void> {
    if (this.isRunning) return;
    
    // Preload resources
    await Promise.all(this.layers.map(layer => layer.preload?.()));
    
    // Initialize layers
    this.layers.forEach(layer => {
      layer.objects.forEach(obj => obj.ready());
      layer.create();
    });

    this.isRunning = true;
    this.lastFrameTime = performance.now();
    this.gameLoop();
  }

  private gameLoop(): void {
    if (!this.isRunning) return;

    const now = performance.now();
    const deltaTime = (now - this.lastFrameTime) / 1000;
    this.lastFrameTime = now;

    // Update
    this.layers.forEach(layer => {
      layer.objects.forEach(obj => {
        obj.update(deltaTime);
        obj.components.forEach(component => component.update(deltaTime));
      });
    });

    // Render
    this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
    this.layers.forEach(layer => {
      layer.objects.forEach(obj => {
        obj.draw();
        obj.components.forEach(component => component.draw());
      });
    });

    requestAnimationFrame(() => this.gameLoop());
  }

  stop(): void {
    this.isRunning = false;
  }
}